﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TicketsPhone.Domain.Entities;
using System.Data;

namespace TicketsPhone.Domain.Access
{
    public class TurnoRepositorio : ConexionSql<Turno>, ICrud<Turno>
    {

        public int Crear()
        {
            CrearComando("spTurno_Crear");
            AgregarParametros();
            return Convert.ToInt32(ExecuteScalar());
        }


        public bool Editar()
        {
            throw new NotImplementedException();
        }

        public bool Eliminar(int id)
        {
            throw new NotImplementedException();
        }

        public Turno Cargar(int id)
        {
            CrearComando("spTurno_Cargar");
            AgregarParametro("@IdTurno", id, ParameterDirection.Input, DbType.Int32);
            ExecuteReader();
            Turno obj = new Turno();

            while (Read())
            {
                
                obj.IdTurno = GetIntValue("IdTurno");
                obj.IdEstadoTurno = (EstadoTurno)GetIntValue("IdEstadoTurno");
                obj.IdSucursal = GetIntValue("IdSucursal");
                obj.Tramite.IdTramite = GetIntValue("IdTramite");
                obj.Tramite.Nombre = GetStringValue("tramite");
                obj.Usuario.IdUsuario = GetIntValue("IdUsuario");
                obj.Usuario.Nombre = GetStringValue("Email");
                obj.HoraInicio = GetTimeValue("HoraInicio");
                obj.HoraFin = GetTimeValue("HoraFin");
                obj.FechaSolicitud = GetDateValue("FechaSolicitud");
                obj.FechaTurno = GetDateValue("FechaTurno");
                obj.Codigo = GetStringValue("Codigo");
                
            }

            return obj;
        }

        public List<Turno> ObtenerTodos()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Valida que el código que se este enviando este disponible para asignar. El codigo se puede repetir solo en el estado de finalizacion.
        /// </summary>
        /// <param name="codigo">codigo a validar</param>
        /// <param name="estado">Estado en el que se puede repetir el turno</param>
        /// <returns></returns>
        public bool EsCodigoValido(string codigo, EstadoTurno estado)
        {
            CrearComando("spTurno_EsCodigoValido");
            AgregarParametro("@Codigo", codigo, ParameterDirection.Input, DbType.String);
            AgregarParametro("@IdEstadoTurno", Convert.ToInt32(estado), ParameterDirection.Input, DbType.Int32);
            return Convert.ToInt32(ExecuteScalar())==0;
        }

        /// <summary>
        /// Cuenta el número de turnos que se han solicitado y se cruzan con determinada hora y fecha en una sucursal.
        /// Solo tiene en cuenta turnos en estado que no sea Cerrado
        /// </summary>
        /// <returns></returns>
        public int ContarTurnosSimultaneos()
        {
            CrearComando("spTurno_ContarTurnosSimultaneos");
            AgregarParametro("@IdEstadoTurno", EstadoTurno.Aceptado, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdSucursal", Objeto.IdSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@HoraInicio", Objeto.HoraInicio.ToDateTime(), ParameterDirection.Input, DbType.Time);
            AgregarParametro("@HoraFin", Objeto.HoraFin.ToDateTime(), ParameterDirection.Input, DbType.Time);
            AgregarParametro("@FechaTurno", Objeto.FechaTurno, ParameterDirection.Input, DbType.DateTime);
            return Convert.ToInt32(ExecuteScalar());
        }

        /// <summary>
        /// Actualiza el estado de un turno dependiendo del ID
        /// </summary>
        /// <param name="idTurno">id del turno solicitado</param>
        /// <param name="nuevoEstado">estado en el que debe quedar el turno</param>
        /// <param name="mensajeEnviado">Tiene el estado si el mensaje fué enviado o no</param>
        public void EditarEstadoTurno(int idTurno, EstadoTurno nuevoEstado)
        {
            CrearComando("spTurno_EditarEstadoTurno");
            AgregarParametro("@IdEstadoTurno", nuevoEstado, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdTurno", idTurno, ParameterDirection.Input, DbType.Int32);
            //AgregarParametro("@MensajeEnviado", mensajeEnviado, ParameterDirection.Input, DbType.Boolean);
            ExecuteNonQuery();
        }


        /// <summary>
        /// Atiende un turno y se le cambia el estado y se ingresann los comentarios
        /// </summary>
        /// <param name="idTurno"></param>
        /// <param name="nuevoEstado"></param>
        /// <param name="comentarios"></param>
        public void AtenderTurno(int idTurno, EstadoTurno nuevoEstado, string comentarios)
        {
            CrearComando("spTurno_AtenderTurno");
            AgregarParametro("@IdEstadoTurno", nuevoEstado, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdTurno", idTurno, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@Comentarios", comentarios == null ? string.Empty : comentarios, ParameterDirection.Input, DbType.String);
            ExecuteNonQuery();
        }

        public List<Turno> ObtenerTurnosSolicitados()
        {
            CrearComando("spTurno_ObtenerTurnosSolicitados");
            AgregarParametro("@IdEstadoTurnoSolicitado", EstadoTurno.Solicitado, ParameterDirection.Input, DbType.Int32);
            ExecuteReader();
            List<Turno> lista = new List<Turno>();

            while (Read())
            {
                Turno obj = new Turno();
                obj.IdTurno = GetIntValue("IdTurno");
                obj.IdEstadoTurno = (EstadoTurno)GetIntValue("IdEstadoTurno");
                obj.IdSucursal = GetIntValue("IdSucursal");
                obj.Tramite.IdTramite = GetIntValue("IdTramite");
                obj.Usuario.IdUsuario = GetIntValue("IdUsuario");
                obj.Usuario.Nombre = GetStringValue("Email");
                obj.HoraInicio = GetTimeValue("HoraInicio");
                obj.HoraFin = GetTimeValue("HoraFin");
                obj.FechaSolicitud = GetDateValue("FechaSolicitud");
                obj.FechaTurno = GetDateValue("FechaTurno");
                obj.Codigo = GetStringValue("Codigo");
                lista.Add(obj);
            }

            return lista;
        }

        /// <summary>
        /// Retorna los turnos que se encuentran en determinado estado
        /// </summary>
        /// <param name="estado"></param>
        /// <returns></returns>
        public List<Turno> ObtenerTurnos(EstadoTurno estado)
        { 
            CrearComando("spTurno_ObtenerTurnosPorEstado");
            AgregarParametro("@IdEstadoTurno", estado, ParameterDirection.Input, DbType.Int32);
            ExecuteReader();
            List<Turno> lista = new List<Turno>();

            while (Read())
            {
                Turno obj = new Turno();
                obj.IdTurno = GetIntValue("IdTurno");
                obj.IdEstadoTurno = (EstadoTurno)GetIntValue("IdEstadoTurno");
                obj.IdSucursal = GetIntValue("IdSucursal");
                obj.Tramite.IdTramite = GetIntValue("IdTramite");
                obj.Usuario.IdUsuario = GetIntValue("IdUsuario");
                obj.Usuario.Nombre = GetStringValue("Email");
                obj.HoraInicio = GetTimeValue("HoraInicio");
                obj.HoraFin = GetTimeValue("HoraFin");
                obj.FechaSolicitud = GetDateValue("FechaSolicitud");
                obj.FechaTurno = GetDateValue("FechaTurno");
                obj.Codigo = GetStringValue("Codigo");
                lista.Add(obj);
            }

            return lista;
        }

        /// <summary>
        /// Listado de turnos activos en una sucursal
        /// </summary>
        /// <param name="idSucursal">id de la sucursal que trae loos turnos</param>
        /// <param name="soloDesdeYa">Solo trae los turnos que empiezan a correr desde hace una hora</param>
        public List<Turno> ObtenerTurnosActivosPorSucursal(int idSucursal, bool soloDesdeYa)
        {
            return ObtenerTurnosActivosPorSucursal(idSucursal, DateTime.Now.AddHours(-1), DateTime.Now.AddDays(2));
        }

        /// <summary>
        /// Listado de turnos activos en una sucursal
        /// </summary>
        /// <param name="idSucursal"></param>
        /// <param name="fechaInicio"></param>
        /// <param name="fechaFin"></param>
        /// <returns></returns>
        public List<Turno> ObtenerTurnosActivosPorSucursal(int idSucursal, DateTime fechaInicio, DateTime fechaFin)
        {
            CrearComando("spTurno_ObtenerTurnosActivosPorSucursal");
            AgregarParametro("@IdEstadoTurno", EstadoTurno.Aceptado, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdSucursal", idSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@FechaInicio", fechaInicio, ParameterDirection.Input, DbType.DateTime);
            AgregarParametro("@FechaFin", fechaFin, ParameterDirection.Input, DbType.DateTime);

            ExecuteReader();
            List<Turno> lista = new List<Turno>();

            while (Read())
            {
                Turno obj = new Turno();
                obj.IdTurno = GetIntValue("IdTurno");
                obj.IdEstadoTurno = (EstadoTurno)GetIntValue("IdEstadoTurno");
                obj.IdSucursal = GetIntValue("IdSucursal");
                obj.Tramite.IdTramite = GetIntValue("IdTramite");
                obj.Tramite.Nombre = GetStringValue("tramite");
                obj.Usuario.IdUsuario = GetIntValue("IdUsuario");
                obj.Usuario.Nombre = GetStringValue("Email");
                obj.HoraInicio = GetTimeValue("HoraInicio");
                obj.HoraFin = GetTimeValue("HoraFin");
                obj.FechaSolicitud = GetDateValue("FechaSolicitud");
                obj.FechaTurno = GetDateValue("FechaTurno");
                obj.Codigo = GetStringValue("Codigo");
                lista.Add(obj);
            }

            return lista;
        }

       


        public List<Turno> Filtrar()
        {
            throw new NotImplementedException();
        }

        private void AgregarParametros()
        {
            AgregarParametro("@IdTurno", Objeto.IdTurno, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdTramite", Objeto.Tramite.IdTramite, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdUsuario", Objeto.Usuario.IdUsuario, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@IdSucursal", Objeto.IdSucursal, ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@FechaSolicitud", Objeto.FechaSolicitud, ParameterDirection.Input, DbType.DateTime);
            AgregarParametro("@IdEstadoTurno", Convert.ToInt32(Objeto.IdEstadoTurno), ParameterDirection.Input, DbType.Int32);
            AgregarParametro("@Codigo", Objeto.Codigo, ParameterDirection.Input, DbType.String);
            AgregarParametro("@HoraInicio", Objeto.HoraInicio.ToDateTime(), ParameterDirection.Input, DbType.Time);
            AgregarParametro("@HoraFin", Objeto.HoraFin.ToDateTime(), ParameterDirection.Input, DbType.Time);
            AgregarParametro("@FechaTurno", Objeto.FechaTurno, ParameterDirection.Input, DbType.DateTime);
        }
    }
}
